{
buf_ioreq_t *buf_req = NULL;
ioreq_t req;
- int qw = 0;
+ int qw;
if (!buffered_io_page)
return;
while (buffered_io_page->read_pointer !=
buffered_io_page->write_pointer) {
- memset(&req, 0, sizeof(req));
- buf_req = &buffered_io_page->buf_ioreq[buffered_io_page->read_pointer %
- IOREQ_BUFFER_SLOT_NUM];
+ buf_req = &buffered_io_page->buf_ioreq[
+ buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
req.size = 1UL << buf_req->size;
req.count = 1;
req.addr = buf_req->addr;
req.data = buf_req->data;
req.state = STATE_IOREQ_READY;
- req.dir = buf_req->dir;
+ req.dir = buf_req->dir;
+ req.df = buf_req->df;
req.type = buf_req->type;
- qw = req.size == 8;
+ req.data_is_ptr = 0;
+ qw = (req.size == 8);
if (qw) {
- buf_req = &buffered_io_page->buf_ioreq[(buffered_io_page->read_pointer+1) %
- IOREQ_BUFFER_SLOT_NUM];
+ buf_req = &buffered_io_page->buf_ioreq[
+ (buffered_io_page->read_pointer+1) % IOREQ_BUFFER_SLOT_NUM];
req.data |= ((uint64_t)buf_req->data) << 32;
}
/* ignore READ ioreq_t and anything buffered io can't deal with */
if (p->dir == IOREQ_READ || p->addr > 0xFFFFFUL ||
- p->data_is_ptr || p->df || p->count != 1)
+ p->data_is_ptr || p->count != 1)
return 0;
for (i = 0; i < HVM_BUFFERED_IO_RANGE_NR; i++) {
bp.type = p->type;
bp.dir = p->dir;
+ bp.df = p->df;
switch (p->size) {
case 1:
bp.size = 0;
#include <xen/types.h>
#include <xen/hvm/save.h>
-void
-arch_hvm_save(struct hvm_save_header *hdr)
+void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr)
{
unsigned int i;
hdr->cpuid[i] = ia64_get_cpuid(i);
}
-int
-arch_hvm_load(struct hvm_save_header *hdr)
+int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
{
unsigned int i;
if (hdr->magic != HVM_FILE_MAGIC) {
/* Ensure buffered_iopage fits in a page */
BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE);
- /* Return 0 for the cases we can't deal with. */
- if ( (p->addr > 0xffffful) || p->data_is_ptr || p->df || (p->count != 1) )
- {
- gdprintk(XENLOG_DEBUG, "slow ioreq. type:%d size:%"PRIu64" addr:0x%"
- PRIx64" dir:%d ptr:%d df:%d count:%"PRIu64"\n",
- p->type, p->size, p->addr, !!p->dir,
- !!p->data_is_ptr, !!p->df, p->count);
+ /*
+ * Return 0 for the cases we can't deal with:
+ * - 'addr' is only a 20-bit field, so we cannot address beyond 1MB
+ * - we cannot buffer accesses to guest memory buffers, as the guest
+ * may expect the memory buffer to be synchronously accessed
+ * - the count field is usually used with data_is_ptr and since we don't
+ * support data_is_ptr we do not waste space for the count field either
+ */
+ if ( (p->addr > 0xffffful) || p->data_is_ptr || (p->count != 1) )
return 0;
- }
bp.type = p->type;
bp.dir = p->dir;
+ bp.df = p->df;
switch ( p->size )
{
case 1:
#include <asm/hvm/support.h>
#include <public/hvm/save.h>
-void
-arch_hvm_save(struct hvm_save_header *hdr)
+void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr)
{
uint32_t eax, ebx, ecx, edx;
hdr->pad0 = 0;
}
-int
-arch_hvm_load(struct hvm_save_header *hdr)
+int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
{
uint32_t eax, ebx, ecx, edx;
+
if ( hdr->magic != HVM_FILE_MAGIC )
{
gdprintk(XENLOG_ERR,
}
cpuid(1, &eax, &ebx, &ecx, &edx);
- /*TODO: need to define how big a difference is acceptable */
+ /* TODO: need to define how big a difference is acceptable? */
if ( hdr->cpuid != eax )
gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
"does not match host (%#"PRIx32").\n", hdr->cpuid, eax);
+ /* VGA state is not saved/restored, so we nobble the cache. */
+ d->arch.hvm_domain.stdvga.cache = 0;
+
return 0;
}
gdprintk(XENLOG_INFO, "entering stdvga and caching modes\n");
}
else if ( prev_stdvga && !s->stdvga )
+ {
gdprintk(XENLOG_INFO, "leaving stdvga\n");
+ }
}
static void stdvga_outv(uint64_t addr, uint64_t data, uint32_t size)
buf = mmio_op(s, p);
break;
default:
- gdprintk(XENLOG_ERR, "unsupported mmio request type:%d "
+ gdprintk(XENLOG_WARNING, "unsupported mmio request type:%d "
"addr:0x%04x data:0x%04x size:%d count:%d state:%d "
"isptr:%d dir:%d df:%d\n",
p->type, (int)p->addr, (int)p->data, (int)p->size,
else
hdr.changeset = -1ULL; /* Unknown */
- arch_hvm_save(&hdr);
+ arch_hvm_save(d, &hdr);
if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
{
if ( hvm_load_entry(HEADER, h, &hdr) != 0 )
return -1;
- if ( arch_hvm_load(&hdr) )
+ if ( arch_hvm_load(d, &hdr) )
return -1;
c = strrchr(xen_changeset(), ':');
typedef struct shared_iopage shared_iopage_t;
struct buf_ioreq {
- uint8_t type; /* I/O type */
- uint8_t dir:1; /* 1=read, 0=write */
- uint8_t size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
- uint32_t addr:20;/* physical address */
- uint32_t data; /* data */
+ uint8_t type; /* I/O type */
+ uint8_t df:1; /* EFLAGS.DF */
+ uint8_t dir:1; /* 1=read, 0=write */
+ uint8_t size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
+ uint32_t addr:20;/* physical address */
+ uint32_t data; /* data */
};
typedef struct buf_ioreq buf_ioreq_t;
/* Arch-specific definitions. */
struct hvm_save_header;
-void arch_hvm_save(struct hvm_save_header *hdr);
-int arch_hvm_load(struct hvm_save_header *hdr);
+void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr);
+int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr);
#endif /* __XEN_HVM_SAVE_H__ */